package zjf.vo;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.net.ssl.SSLContext;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import zjf.util.StringUtil;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 高级接口工具类
 */
public class AdvancedUtil {
	private static Logger log = LoggerFactory.getLogger(AdvancedUtil.class);
	/**
	 * 支付参数组织
	 * @param money
	 * @param openid
	 * @param ip
	 * @return
	 */
	public static com.alibaba.fastjson.JSONObject makeParams(String APPID,String BUSINESSNO,String APPKEY,String money,String openid,String ip,String pname,String url,String attach){
		StringBuffer stringBuffer=new StringBuffer();
		
		stringBuffer.append("<xml>");//
		stringBuffer.append("<appid>"+APPID+"</appid>");//
		if(!StringUtil.isNullOrEmpty(attach)&&attach.startsWith("qrscene")){
			//qrscene_2
			System.out.println("save eventKey:"+attach);
			String string[]=attach.split("_");
			if(string!=null&&string.length==2){
				attach=string[1];
			}
		}
		stringBuffer.append("<attach>"+attach+"</attach>");
		stringBuffer.append("<body>"+pname+"</body>");//20160401 zxg
		
		stringBuffer.append("<detail>"+pname+"</detail>");//20160401 zxg
		stringBuffer.append("<device_info>WEB"+"</device_info>");//设备号
		stringBuffer.append("<fee_type>CNY</fee_type>");
		stringBuffer.append("<mch_id>"+BUSINESSNO+"</mch_id>");//商户号
		String nonce_str=Sign.create_nonce_str().replace("-", "");
		stringBuffer.append("<nonce_str>"+nonce_str+"</nonce_str>");
		
		stringBuffer.append("<notify_url>"+url+"</notify_url>");
		stringBuffer.append("<openid>"+openid+"</openid>");
		
		SimpleDateFormat format =new SimpleDateFormat("yyyyMMddHHmmss",Locale.getDefault());
		Date date =new Date();
		String key = format.format(date);
		Random random= new Random();
		int rannum = (int) (random.nextDouble() * (99999 - 10000 + 1)) + 10000;// 获取5位随机数  
		String out_trade_no=key+rannum;
		
		stringBuffer.append("<out_trade_no>"+out_trade_no+"</out_trade_no>");
		stringBuffer.append("<spbill_create_ip>"+ip+"</spbill_create_ip>");//用户端ip
		stringBuffer.append("<total_fee>"+money+"</total_fee>");
		stringBuffer.append("<trade_type>JSAPI"+"</trade_type>");
		
		SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
		
		parameters.put("appid",APPID);
		parameters.put("attach", attach);
		parameters.put("body",pname);
		parameters.put("detail",pname);
		parameters.put("device_info","WEB");//设备号
		parameters.put("fee_type","CNY");
		parameters.put("mch_id",BUSINESSNO);//商户号
		parameters.put("nonce_str",nonce_str);
		parameters.put("notify_url",url);
		parameters.put("openid",openid);
		parameters.put("out_trade_no",out_trade_no);
		parameters.put("spbill_create_ip",ip);//用户端ip
		parameters.put("total_fee",money);////商品金额,以分为单位  
		parameters.put("trade_type","JSAPI");
		//String mySign = createSign(characterEncoding,parameters);
		String signString=MD5Util.createSign("UTF-8",parameters,APPKEY);
		stringBuffer.append("<sign>"+signString+"</sign>");//签名
		stringBuffer.append("</xml>");//
		com.alibaba.fastjson.JSONObject js=new com.alibaba.fastjson.JSONObject();
		js.put("sign", signString);
		js.put("prepay_id", getUnifiedOrder(stringBuffer.toString()));
		return js;
	}	
	/**
	 * 统一下单
	 * 
	 * @param appId 公众账号的唯一标识
	 * @param appSecret 公众账号的密钥
	 */
	public static String getUnifiedOrder(String json) {
		// 拼接请求地址
		String requestUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		String prepay_id=null;
		 try {
	            URL url = new URL(requestUrl);
	            URLConnection con = url.openConnection();
	            con.setDoOutput(true);
//	            con.setRequestProperty("Pragma:", "no-cache");
	            con.setRequestProperty("Cache-Control", "no-cache");
	            con.setRequestProperty("Content-Type", "text/xml");

	            OutputStreamWriter out = new OutputStreamWriter(con
	                    .getOutputStream());    
	            String xmlInfo =json;
	            log.debug("urlStr=" + requestUrl);
	            log.debug("xmlInfo=" + xmlInfo);
//	            out.write(new String(xmlInfo.getBytes("ISO-8859-1")));
	            out.write(new String(xmlInfo.getBytes("utf-8")));
	            out.flush();
	            out.close();
	            BufferedReader br = new BufferedReader(new InputStreamReader(con
	                    .getInputStream()));
	            String line = "";
	            for (line = br.readLine(); line != null; line = br.readLine()) {
	            	if(line.contains("prepay_id")){
	            		String array[]=line.split("\\[");
	            		prepay_id=array[2].split("\\]")[0];
	            	}
	                System.out.println(line);
//	                log.debug("获取支付订单：", line);
	            }
	        } catch (MalformedURLException e) {
	            e.printStackTrace();
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
		return prepay_id;
	}
	/**
	 * 统一下单
	 * 
	 * @param appId 公众账号的唯一标识
	 * @param appSecret 公众账号的密钥
	 */
	public static com.alibaba.fastjson.JSONObject getUnifiedOrderOut(String json) {
		// 拼接请求地址
		String requestUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
		String prepay_id=null;
		com.alibaba.fastjson.JSONObject js=new com.alibaba.fastjson.JSONObject();
		try {
			URL url = new URL(requestUrl);
			URLConnection con = url.openConnection();
			con.setDoOutput(true);
			con.setRequestProperty("Cache-Control", "no-cache");
			con.setRequestProperty("Content-Type", "text/xml");
			
			OutputStreamWriter out = new OutputStreamWriter(con
					.getOutputStream());    
			String xmlInfo =json;
			System.out.println("urlStr=" + requestUrl);
			System.out.println("xmlInfo=" + xmlInfo);
//	            out.write(new String(xmlInfo.getBytes("ISO-8859-1")));
			out.write(new String(xmlInfo.getBytes("utf-8")));
			out.flush();
			out.close();
			BufferedReader br = new BufferedReader(new InputStreamReader(con
					.getInputStream()));
			String line = "";
			StringBuffer stringBuffer=new StringBuffer();
			for (line = br.readLine(); line != null; line = br.readLine()) {
				System.out.println(line);
				stringBuffer.append(line);
			}
			
			try {
				Document document = DocumentHelper.parseText(stringBuffer.toString());
				Element root = document.getRootElement();  
				 for(Iterator it=root.elementIterator();it.hasNext();){       
				        Element element = (Element) it.next();     
				        js.put(element.getName(), element.getText());
				 }  
			} catch (DocumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}    
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return js;
	}
	/**
	 * 获取jsapi_ticket
	 * 
	 * @param appId 公众账号的唯一标识
	 * @param appSecret 公众账号的密钥
	 */
	public static String getJsapiTicket(String access_token) {
		String  ticket = "";
		// 拼接请求地址
		String requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
		requestUrl = requestUrl.replace("ACCESS_TOKEN", access_token);
		System.out.println("requestUrl="+requestUrl);
		// 获取网页授权凭证
		JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
		if (null != jsonObject) {
			try {
				ticket=jsonObject.getString("ticket");
			} catch (Exception e) {
				int errorCode = jsonObject.getIntValue("errcode");
				String errorMsg = jsonObject.getString("errmsg");
				log.error("获取access token失败 errcode:{} errmsg:{}", errorCode, errorMsg);
			}
		}
		return ticket;
	}

	/**
	 * 获取access token
	 * 
	 * @param appId 公众账号的唯一标识
	 * @param appSecret 公众账号的密钥
	 */
	public static WeixinOauth2Token getAccessToken(String appId, String appSecret) {
		WeixinOauth2Token wat = null;
		// 拼接请求地址
		String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
		requestUrl = requestUrl.replace("APPID", appId);
		requestUrl = requestUrl.replace("APPSECRET", appSecret);
		System.out.println("requestUrl="+requestUrl);
		// 获取网页授权凭证
		JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
		if (null != jsonObject) {
			try {
				wat = new WeixinOauth2Token();
				wat.setAccessToken(jsonObject.getString("access_token"));
				wat.setExpiresIn(jsonObject.getIntValue("expires_in"));
			} catch (Exception e) {
				wat = null;
				int errorCode = jsonObject.getIntValue("errcode");
				String errorMsg = jsonObject.getString("errmsg");
				log.error("获取access token失败 errcode:{} errmsg:{}", errorCode, errorMsg);
			}
		}
		return wat;
	}
	/**
	 * 获取网页授权凭证
	 * 
	 * @param appId 公众账号的唯一标识
	 * @param appSecret 公众账号的密钥
	 * @param code
	 * @return WeixinAouth2Token
	 */
	public static WeixinOauth2Token getOauth2AccessToken(String appId, String appSecret, String code) {
		WeixinOauth2Token wat = null;
		// 拼接请求地址
		String requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
		requestUrl = requestUrl.replace("APPID", appId);
		requestUrl = requestUrl.replace("SECRET", appSecret);
		requestUrl = requestUrl.replace("CODE", code);
		System.out.println("requestUrl="+requestUrl);
		// 获取网页授权凭证
		JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
		if (null != jsonObject) {
			try {
				wat = new WeixinOauth2Token();
				wat.setAccessToken(jsonObject.getString("access_token"));
				wat.setExpiresIn(jsonObject.getIntValue("expires_in"));
				wat.setRefreshToken(jsonObject.getString("refresh_token"));
				wat.setOpenId(jsonObject.getString("openid"));
				wat.setScope(jsonObject.getString("scope"));
			} catch (Exception e) {
				wat = null;
				int errorCode = jsonObject.getIntValue("errcode");
				String errorMsg = jsonObject.getString("errmsg");
				log.error("获取网页授权凭证失败 errcode:{} errmsg:{}", errorCode, errorMsg);
			}
		}
		return wat;
	}

	/**
	 * 刷新网页授权凭证
	 * 
	 * @param appId 公众账号的唯一标识
	 * @param refreshToken
	 * @return WeixinAouth2Token
	 */
	public static WeixinOauth2Token refreshOauth2AccessToken(String appId, String refreshToken) {
		WeixinOauth2Token wat = null;
		// 拼接请求地址
		String requestUrl = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
		requestUrl = requestUrl.replace("APPID", appId);
		requestUrl = requestUrl.replace("REFRESH_TOKEN", refreshToken);
		// 刷新网页授权凭证
		JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
		if (null != jsonObject) {
			try {
				wat = new WeixinOauth2Token();
				wat.setAccessToken(jsonObject.getString("access_token"));
				wat.setExpiresIn(jsonObject.getIntValue("expires_in"));
				wat.setRefreshToken(jsonObject.getString("refresh_token"));
				wat.setOpenId(jsonObject.getString("openid"));
				wat.setScope(jsonObject.getString("scope"));
			} catch (Exception e) {
				wat = null;
				int errorCode = jsonObject.getIntValue("errcode");
				String errorMsg = jsonObject.getString("errmsg");
				log.error("刷新网页授权凭证失败 errcode:{} errmsg:{}", errorCode, errorMsg);
			}
		}
		return wat;
	}

	/**
	 * 通过网页授权获取用户信息
	 * 
	 * @param accessToken 网页授权接口调用凭证
	 * @param openId 用户标识
	 * @return SNSUserInfo
	 */
	@SuppressWarnings( { "deprecation", "unchecked" })
	public static SNSUserInfo getSNSUserInfo(String accessToken, String openId) {
		SNSUserInfo snsUserInfo = null;
		// 拼接请求地址
		String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
//		String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
		requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
		// 通过网页授权获取用户信息
		JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);

		if (null != jsonObject) {
			try {
				snsUserInfo = new SNSUserInfo();
				// 用户的标识
				snsUserInfo.setOpenId(jsonObject.getString("openid"));
				// 昵称
				snsUserInfo.setNickname(jsonObject.getString("nickname"));
				// 性别（1是男性，2是女性，0是未知）
				snsUserInfo.setSex(jsonObject.getIntValue("sex"));
				// 用户所在国家
				snsUserInfo.setCountry(jsonObject.getString("country"));
				// 用户所在省份
				snsUserInfo.setProvince(jsonObject.getString("province"));
				// 用户所在城市
				snsUserInfo.setCity(jsonObject.getString("city"));
				// 用户头像
				snsUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));
				// 用户特权信息
				snsUserInfo.setPrivilegeList(JSONArray.toJavaObject(jsonObject.getJSONArray("privilege"), List.class));
			} catch (Exception e) {
				snsUserInfo = null;
				int errorCode = jsonObject.getIntValue("errcode");
				String errorMsg = jsonObject.getString("errmsg");
				log.error("获取用户信息失败 errcode:{} errmsg:{}", errorCode, errorMsg);
				System.out.println("获取用户信息失败 errcode:{} errmsg:{}"+ errorCode+errorMsg);
			}
		}
		return snsUserInfo;
	}


	/**
	 * 获取用户信息
	 * 
	 * @param accessToken 接口访问凭证
	 * @param openId 用户标识
	 * @return WeixinUserInfo
	 */
	public static WeixinUserInfo getUserInfo(String accessToken, String openId) {
		WeixinUserInfo weixinUserInfo = null;
		// 拼接请求地址
		String requestUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
		requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
		// 获取用户信息
		JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);

		if (null != jsonObject) {
			try {
				weixinUserInfo = new WeixinUserInfo();
				// 用户的标识
				weixinUserInfo.setOpenId(jsonObject.getString("openid"));
				// 关注状态（1是关注，0是未关注），未关注时获取不到其余信息
				weixinUserInfo.setSubscribe(jsonObject.getIntValue("subscribe"));
				// 用户关注时间
				weixinUserInfo.setSubscribeTime(jsonObject.getString("subscribe_time"));
				// 昵称
				weixinUserInfo.setNickname(jsonObject.getString("nickname"));
				// 用户的性别（1是男性，2是女性，0是未知）
				weixinUserInfo.setSex(jsonObject.getIntValue("sex"));
				// 用户所在国家
				weixinUserInfo.setCountry(jsonObject.getString("country"));
				// 用户所在省份
				weixinUserInfo.setProvince(jsonObject.getString("province"));
				// 用户所在城市
				weixinUserInfo.setCity(jsonObject.getString("city"));
				// 用户的语言，简体中文为zh_CN
				weixinUserInfo.setLanguage(jsonObject.getString("language"));
				// 用户头像
				weixinUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));
			} catch (Exception e) {
				if (0 == weixinUserInfo.getSubscribe()) {
					log.error("用户{}已取消关注", weixinUserInfo.getOpenId());
				} else {
					int errorCode = jsonObject.getIntValue("errcode");
					String errorMsg = jsonObject.getString("errmsg");
					log.error("获取用户信息失败 errcode:{} errmsg:{}", errorCode, errorMsg);
				}
			}
		}
		return weixinUserInfo;
	}
	/**
	 * 获取Ticket
	 * 
	 * @param accessToken 接口访问凭证
	 * @param openId 用户标识
	 * @return WeixinUserInfo
	 */
	public static String getTicket(String accessToken) {
		String ticket="";
		// 拼接请求地址
		String requestUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKENPOST";
		requestUrl = requestUrl.replace("TOKENPOST", accessToken);

		String infoString="{\"expire_seconds\": 604800, \"action_name\": \"QR_SCENE\", \"action_info\": {\"scene\": {\"scene_id\": 123}}}";
		JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "POST", infoString);
		if (null != jsonObject) {
			try {
				ticket=jsonObject.getString("ticket");
			} catch (Exception e) {
				int errorCode = jsonObject.getIntValue("errcode");
				String errorMsg = jsonObject.getString("errmsg");
				log.error("获取商户信息失败 errcode:{} errmsg:{}", errorCode, errorMsg);
			}
		}
		return ticket;
	}
	/**
	 * 通过ticket换取二维码
	 * 
	 * @param accessToken 接口访问凭证
	 * @param openId 用户标识
	 * @return WeixinUserInfo
	 */
	public static String getTicketUrl(String TICKET) {
		// 拼接请求地址
		String requestUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET";
		requestUrl = requestUrl.replace("TICKET", TICKET);
		JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
		if (null != jsonObject) {
			try {
			} catch (Exception e) {
				int errorCode = jsonObject.getIntValue("errcode");
				String errorMsg = jsonObject.getString("errmsg");
				log.error("通过ticket换取二维码失败 errcode:{} errmsg:{}", errorCode, errorMsg);
			}
		}
		return jsonObject.toString();
	}
	/**
	 * 获取access_token
	 * 
	 * @param accessToken 接口访问凭证
	 * @param openId 用户标识
	 * @return WeixinUserInfo
	 */
	public static String getVerifiedAccessToken(String APPID,String APPSECRET) {
		String codeString="";
		// 拼接请求地址
		String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
		requestUrl = requestUrl.replace("APPID", APPID).replace("APPSECRET", APPSECRET);
		// 获取用户信息
		JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
		if (null != jsonObject) {
			try {
				codeString=jsonObject.getString("access_token");
			} catch (Exception e) {
				int errorCode = jsonObject.getIntValue("errcode");
				String errorMsg = jsonObject.getString("errmsg");
				log.error("获取accessToken失败 errcode:{} errmsg:{}", errorCode, errorMsg);
			}
		}
		return codeString;
	}
public static void main(String[] args) {
}
}
